package com.puzzlebazar.client.squaregrid.model;

import com.puzzlebazar.client.puzzle.model.Move;
import com.puzzlebazar.client.puzzle.model.MoveImpl;
import com.puzzlebazar.client.puzzle.model.PuzzleModelImpl;
import com.puzzlebazar.client.util.GridValidityImpl;
import com.puzzlebazar.client.util.Recti;
import com.puzzlebazar.client.util.Vec2i;



/**
 * @author beaudoin
 *
 * Model for a standard empty square grid
 *
 */
public abstract class SGModelImpl extends PuzzleModelImpl implements SGModel {
    
    /**
	 * 
	 */
	private static final long serialVersionUID = 6583489799631430300L;

	@Override
	public Vec2i getGridSize() {
		return getSize();
	}

	@Override
	public Move resize( Vec2i size ) throws Exception {
		return setSizeAndClear( size );
	}
		
	@Override
	public Move expandBottom(int delta) throws Exception {
		final Vec2i gridSize = getSize();
		return setSizeAndClear( new Vec2i(gridSize.x, gridSize.y+delta) );
	}

	@Override
	public Move expandLeft(int delta) throws Exception {
		final Vec2i gridSize = getSize();
		return setSizeAndClear( new Vec2i(gridSize.x+delta, gridSize.y) );
	}

	@Override
	public Move expandRight(int delta) throws Exception {
		final Vec2i gridSize = getSize();
		return setSizeAndClear( new Vec2i(gridSize.x+delta, gridSize.y) );
	}

	@Override
	public Move expandTop(int delta) throws Exception {
		final Vec2i gridSize = getSize();
		return setSizeAndClear( new Vec2i(gridSize.x, gridSize.y+delta) );
	}		
	
	/**
	 * Sets the size and clears the model
	 * 
	 * @param gridSize The new number of columns/rows
	 * @throws Exception
	 */
	private Move setSizeAndClear( Vec2i gridSize ) throws Exception {
		if( gridSize.equals( getSize() ) ) return null;
		setGridSize( gridSize );
		// TODO Set time and use a better move
		return clear( MoveImpl.NO_TIME );
	}

	@Override
	public boolean isValidCell(Vec2i loc) {
		return GridValidityImpl.isValidCell(loc, getSize());
	}

	@Override
	public boolean isValidVertex(Vec2i loc) {
		return GridValidityImpl.isValidVertex(loc, getSize());
	}	

	@Override
	public boolean isValidVerticalEdge(Vec2i loc) {
		return GridValidityImpl.isValidVerticalEdge(loc, getSize());
	}	

	@Override
	public boolean isValidHorizontalEdge(Vec2i loc) {
		return GridValidityImpl.isValidHorizontalEdge(loc, getSize());
	}

	@Override
	public boolean isValidRect(Recti rect) {
		return GridValidityImpl.isValidRect(rect, getSize());
	}
}
